package titt.io.writer;

import titt.TITTValues;
import titt.head.HeadFactory;
import titt.head.request.RequestHead;
import titt.head.request.form.FormHead;
import titt.head.request.form.MultipartHead;
import titt.io.IOFactory;
import titt.io.encoding.Encoder;
import titt.io.socket.TITTSocket;
import titt.io.socket.out.LengthBufferedOutputStream;
import titt.io.writer.head.HeadWriter;
import titt.type.TypedObject;
import titt.util.Bytes;

public class POSTWriter implements Writer<TypedObject> {
	
	private final TITTSocket ts;
	private final Encoder enc;
	private final RequestHead req;
	
	public POSTWriter(TITTSocket ts, Encoder enc, RequestHead req) {
		this.ts = ts;
		this.enc = enc;
		this.req = req;
	}
	
	@Override
	public void writeValues(TypedObject... values) throws Exception {
		
		String bound = HeadFactory.generateBoundary();
		byte[][] bounds = getBounds(bound);
		
		LengthBufferedOutputStream buf = new LengthBufferedOutputStream();
		HeadWriter hw = IOFactory.createHeadWriter(buf);
		
		for(TypedObject ot : values) {
			
			buf.writeLine(bounds[0]);
			hw.writeHead(new MultipartHead(ot.getType()));
			
			if(!enc.isEncodeable(ot.getType())) 
				buf.writeLine(new byte[1]);
			else
				buf.writeLine(enc.encode(ot.getType(), ot.getObject()));
			
		}
		
		buf.writeLine(bounds[1]);
		buf.flush();
	
		ts.getHeadWriter().writeHead(new FormHead(buf.getLength(), bound, req));

		buf.writeTo(ts.getOutputStream());
		
		ts.getOutputStream().flush();
	}	

	private byte[][] getBounds(String bound) {
		return new byte[][] {
			Bytes.asBytes(TITTValues.MULTIPART_SEPERATOR + bound),
			Bytes.asBytes(TITTValues.MULTIPART_SEPERATOR + bound + TITTValues.MULTIPART_SEPERATOR)
		};
	}
}
